/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "节点/节点.h"
#include "节点/输入输出节点.h"


class C_手动执行节点 : public C_节点基类 {

public:
	C_手动执行节点(S_设备环境& ctx);
	~C_手动执行节点();

	bool	f_update();
	void	f_set是否要更新(bool update);

	uint8		m_执行状态;
	S_Operator* m_执行Ops;

};

C_节点基类* f_node_加载手动执行节点(S_设备环境& ctx, FILE* f);
void		f_node_保存手动执行节点(C_节点基类* n, FILE* f);






class C_循环迭代节点 : public C_节点基类 {
	//C_节点树* m_子树;
public:
	C_循环迭代节点(S_设备环境& ctx);
	~C_循环迭代节点();

	bool	f_update();

	std::vector<C_节点基类*> m_InNodes;
	std::vector<C_节点基类*> m_OutNudes;
	void f_get子集输入节点(std::vector<C_节点基类*>& inNodes);
	void f_get子集输出节点(std::vector<C_节点基类*>& outNodes);

	int16	f_可添加删除插座起始位置(E_插座方向 方向) { 
		if (方向 == E_插座方向::e_插座Type_输入) return 3;
		return 1; 
	}

	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建循环迭代节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载循环迭代节点(S_设备环境& ctx, FILE* f);
void		f_node_保存循环迭代节点(C_节点基类* n, FILE* f);





class C_跳过节点 : public C_节点基类 {
	
public:
	C_跳过节点(S_设备环境& ctx);
	~C_跳过节点();

	S_Props	m_跳过返回;

	bool	f_update();

	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建跳过节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载跳过节点(S_设备环境& ctx, FILE* f);
void		f_node_保存跳过节点(C_节点基类* n, FILE* f);





class C_循环节点 : public C_节点基类 {
	
public:
	C_循环节点(S_设备环境& ctx);
	~C_循环节点();

	bool	f_update();

	class C_循环尾节点* m_循环尾节点;
	S_Props				m_循环尾节点名称;
	//std::vector<C_节点基类*> m_InNodes;
	//std::vector<C_节点基类*> m_OutNudes;
	//void f_get子集输入节点(std::vector<C_节点基类*>& inNodes);
	//void f_get子集输出节点(std::vector<C_节点基类*>& outNodes);

	int16	f_可添加删除插座起始位置(E_插座方向 方向) {
		if (方向 == E_插座方向::e_插座Type_输入) return 3;
		return 1;
	}

	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建循环节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载循环节点(S_设备环境& ctx, FILE* f);
void		f_node_保存循环节点(C_节点基类* n, FILE* f);




class C_迭代节点 : public C_节点基类 {

public:
	C_迭代节点(S_设备环境& ctx);
	~C_迭代节点();

	bool	f_update();

	class C_循环尾节点* m_循环尾节点;
	S_Props				m_循环尾节点名称;
	S_Props				m_开启多线程;

	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);
	C_插座基类* f_动态添加插座(E_插座方向 方向, std::vector<S_添加的插座>& 添加的插座);
	int32		f_动态删除插座(E_插座方向 方向, std::vector<S_删除的插座>& 删除的插座);
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_创建迭代节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载迭代节点(S_设备环境& ctx, FILE* f);
void		f_node_保存迭代节点(C_节点基类* n, FILE* f);



class C_循环尾节点 : public C_节点基类 {

public:
	C_循环尾节点(S_设备环境& ctx);
	~C_循环尾节点();

	C_节点基类* m_循环节点;

	bool		f_update();
	std::string	f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放);

	C_插座基类* f_动态添加插座(E_插座方向 方向, std::vector<S_添加的插座>& 添加的插座);
	int32		f_动态删除插座(E_插座方向 方向, std::vector<S_删除的插座>& 删除的插座);
};

C_节点基类* f_node_创建循环尾节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载循环尾节点(S_设备环境& ctx, FILE* f);
void		f_node_保存循环尾节点(C_节点基类* n, FILE* f);


void f_配对循环节点头和尾(C_节点基类* node_b, C_循环尾节点* node_e);
//void f_配对循环节点头和尾(C_节点基类* node_b, C_循环尾节点* node_e);







class C_分支判断节点 : public C_节点基类 {
	
public:
	C_分支判断节点(S_设备环境& ctx);
	~C_分支判断节点();

	S_Props m_反向;
	S_Props m_布尔;
	S_Props m_Case;

	bool		f_update();
	std::string	DEF_节点编译函数;
	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
	
};

C_节点基类* f_node_创建分支判断节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载分支判断节点(S_设备环境& ctx, FILE* f);
void		f_node_保存分支判断节点(C_节点基类* n, FILE* f);







class C_包节点 : public C_节点基类 {
	std::vector<C_节点基类*> m_InNodes;
	std::vector<C_节点基类*> m_OutNudes;
	S_动画曲线组* m_动画曲线列表;
public:
	C_包节点(S_设备环境& ctx, C_节点树* link_tree);
	~C_包节点();

	void f_get子集输入节点(std::vector<C_节点基类*>& inNodes);
	void f_get子集输出节点(std::vector<C_节点基类*>& outNodes);

	bool          f_update();
	S_动画曲线组* f_getAN曲线();
	uint32        f_getAN曲线数量();
	S_物体*       f_get虚拟体();
	void          f_入回收();
	void          f_回收();
	void          f_读取(FILE* f);
	void          f_写入(FILE* f);
};

C_节点基类* f_node_创建包节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载包节点(S_设备环境& ctx, FILE* f);
void		f_node_保存包节点(C_节点基类* n, FILE* f);



